package com.qyer.search.model.result;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.qyer.search.Constants;
import com.qyer.search.model.lastminute.SKU;
import com.qyer.search.model.lastminute.VSKU;
import com.qyer.search.utils.ListUtils;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Created by tangzheng on 16/7/18.
 */
public class SearchEntity {

  @JsonProperty
  protected List<VSKU> skus;
  @JsonProperty("skus_size")
  protected int packageSize;
  @JsonProperty
  protected List<VSKU> marketSkus;
  @JsonProperty
  protected List<VSKU> commonSkus;

  protected List<VSKU> preferSkus;
  protected List<VSKU> generalSkus;
  @JsonIgnore
  protected Set<Integer> idSet;

  public SearchEntity() {
    this.skus = Lists.newArrayListWithExpectedSize(50);
    this.idSet = Sets.newHashSetWithExpectedSize(skus.size());
    this.commonSkus = Lists.newArrayListWithExpectedSize(40);
    this.marketSkus = Lists.newArrayListWithExpectedSize(10);
    this.preferSkus = Lists.newArrayListWithExpectedSize(40);
    this.generalSkus = Lists.newArrayListWithExpectedSize(40);
    this.packageSize = 0;
  }

  public SearchEntity(int listSize) {
    this.skus = Lists.newArrayListWithCapacity(listSize);
    this.idSet = Sets.newHashSetWithExpectedSize(listSize);
    int size = (listSize/3)*2;
    this.commonSkus = Lists.newArrayListWithExpectedSize(size);
    this.preferSkus = Lists.newArrayListWithExpectedSize(size);
    this.generalSkus = Lists.newArrayListWithExpectedSize(size);
    this.marketSkus = Lists.newArrayListWithExpectedSize(10);
    this.packageSize = 0;
  }

  public void addPrefer(VSKU vsku){
    this.preferSkus.add(vsku);
  }

  public void addPrefer(List<VSKU> vskus){
    this.preferSkus.addAll(vskus);
  }

  public void addGeneral(VSKU vsku){
    this.generalSkus.add(vsku);
  }

  public void addGeneral(List<VSKU> vskus){
    this.generalSkus.addAll(vskus);
  }

  public List<VSKU> getPreferSkus() {
    return preferSkus;
  }

  public void setPreferSkus(List<VSKU> preferSkus) {
    this.preferSkus = preferSkus;
  }

  public List<VSKU> getGeneralSkus() {
    return generalSkus;
  }

  public void setGeneralSkus(List<VSKU> generalSkus) {
    this.generalSkus = generalSkus;
  }

  // 去重
  public void addSku(VSKU sku) {
    int id = sku.getId();
    if (!idSet.contains(id)) {
      this.skus.add(sku);
      this.idSet.add(id);
      this.packageSize ++;
      if(sku.getMarketInfo() > 200){
        this.commonSkus.add(sku);
      }else {
        this.marketSkus.add(sku);
        //System.out.println("MAR:"+id);
      }
    }else {
      System.out.println("id set 重复:" + id);
    }
  }

  // 这里不判断去重, 因为去重的工作在addSku做了, 这个功能是给排序准备的
  public void addSkus(List<VSKU> skus) {
    if (CollectionUtils.isEmpty(skus)) {
      return;
    }
    this.skus.addAll(skus);
    this.packageSize += skus.size();
  }

  public void addCommonSkus(List<VSKU> skus){
    if (CollectionUtils.isEmpty(skus)) {
      return;
    }
    this.skus.addAll(skus);
    this.commonSkus.addAll(skus);
    this.packageSize += skus.size();
  }

  public void addMarketSkus(List<VSKU> skus){
    if (CollectionUtils.isEmpty(skus)) {
      return;
    }
    this.skus.addAll(skus);
    this.marketSkus.addAll(skus);
    this.packageSize += skus.size();
  }
  public void add(SearchEntity searchEntity){
    if(CollectionUtils.isEmpty(searchEntity.getSkus()))
      return;
    this.skus.addAll(searchEntity.getSkus());
    this.idSet.addAll(searchEntity.getIdSet());
    if(CollectionUtils.isNotEmpty(searchEntity.getCommonSkus())){
      this.commonSkus.addAll(searchEntity.getCommonSkus());
    }
    if(CollectionUtils.isNotEmpty(searchEntity.getMarketSkus())){
      this.marketSkus.addAll(searchEntity.getMarketSkus());
    }
    this.packageSize += searchEntity.getPackageSize();
  }

  public List<VSKU> getSkus() {
    return skus;
  }

  public void setSkus(List<VSKU> skus) {
    this.skus = skus;
  }

  public int getPackageSize() {
    return packageSize;
  }

  public void setPackageSize(int packageSize) {
    this.packageSize = packageSize;
  }

  public Set<Integer> getIdSet() {
    return idSet;
  }

  public void setIdSet(Set<Integer> idSet) {
    this.idSet = idSet;
  }

  public void resize(int limit){
    this.skus = ListUtils.ToSubList(this.skus, 0, limit);
    Set<Integer> set = Sets.newHashSetWithExpectedSize(limit);
    for(int i = 0; i < this.skus.size(); i++){
      set.add(this.skus.get(i).getId());
    }
    this.idSet = set;
  }

  public List<VSKU> getMarketSkus() {
    return marketSkus;
  }

  public void setMarketSkus(List<VSKU> marketSkus) {
    this.marketSkus = marketSkus;
  }

  public List<VSKU> getCommonSkus() {
    return commonSkus;
  }

  public void setCommonSkus(List<VSKU> commonSkus) {
    this.commonSkus = commonSkus;
  }

  public void sub(int from, int to){
    this.skus = ListUtils.ToSubList(this.skus, from, to);
  }

  public VInnerResult getMap(int from, int to){
    List<Integer> list = new ArrayList<>((to - from));
    for(VSKU vsku:this.skus){
      list.add(vsku.getId());
    }
    //System.out.println("size:"+packageSize);
    return new VInnerResult(this.packageSize, list);
  }

  public VInnerResult getMap(){
    List<Integer> list = new ArrayList<>();
    for(VSKU vsku:this.skus){
      list.add(vsku.getId());
    }
    //System.out.println("size:"+packageSize);
    return new VInnerResult(this.packageSize, list);
  }


  /*public VInnerResult getMap(int from, int to){
    List<Integer> listI = new ArrayList<>();
    List<VSKU> list = new ArrayList<>(this.skus);
    list = ListUtils.ToSubList(list, from, to);
    for(VSKU vsku:list){
      listI.add(vsku.getId());
    }
    return new VInnerResult(this.packageSize, listI);
  }*/

  public void resizeSKUs(int from, int to){
    this.skus = ListUtils.ToSubList(this.skus, from, to);
  }

  public SearchPackage toSP(){
    SearchPackage searchPackage = new SearchPackage(this.skus.size());
    List<SKU> list = new ArrayList<>(this.skus.size());
    for(int i = 0; i<this.skus.size(); i++){
      list.add(skus.get(i).toSKU());
    }
    searchPackage.addSkus(list);
    return searchPackage;
  }

  @Override public String toString() {
    return "SearchEntity{" +
      "skus=" + skus +
      '}';
  }
}
